package client;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JToggleButton;

import java.awt.BorderLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.SwingConstants;

import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;

import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.MatteBorder;
import javax.swing.border.SoftBevelBorder;

import java.awt.Font;

import javax.swing.JSeparator;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ClientGUI {

	private Client c;
	private BotPlayer bp;
	private JFrame frmBadugi;

	private JLabel statusBar;

	private JTextField tfPort;
	private JTextField tfHost;
	private JTextField tfNick;
	private JButton btnConnect;
	private JButton btnDisconnect;

	private JButton btnBet;
	private JButton btnRaise;
	private JButton btnCheck;
	private JButton btnCall;
	private JButton btnAllin;
	private JButton btnFold;
	private JTextField tfRaise;

	private JLabel lblBalance;
	private JLabel lblBet;
	private JLabel lblPot;
	private JLabel lblMaxBet;

	private JToggleButton tgCard1;
	private JToggleButton tgCard2;
	private JToggleButton tgCard3;
	private JToggleButton tgCard4;

	private JButton btnExchange;

	private JButton btnStart;

	public OpponentPanel[] op;

	/**
	 * Array with cards that will be exchanged
	 */
	private boolean[] exchangedCards = new boolean[4];
	private JLabel lblNewLabel_1;

	public void resetBets() {
		c.maxBet = 0;
		c.pot = 0;
		c.playersBet = 0;
		setCashLbl("maxbet", c.maxBet);
		setCashLbl("pot", c.pot);
		setCashLbl("bet", c.playersBet);
		for (int i = 0; i < op.length; i++) {
			if (op[i].playersBet != 0) {
				op[i].playersBet = 0;
				op[i].updateLabels(op[i].playersBet, op[i].playersBalance);
			}
		}
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ClientGUI window = new ClientGUI();
					window.frmBadugi.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public void setCards(int i, String card) {
		String[] cardArray = card.split("-");
		int[] cardints = new int[2];
		cardints[0] = Integer.parseInt(cardArray[0]);
		cardints[1] = Integer.parseInt(cardArray[1]);
		String[] suits = { "\u2663", "\u2666", "\u2665", "\u2660" }; // club,
																		// diamond,
																		// heart,
																		// spade

		String[] values = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10",
				"J", "Q", "K" };
		// prepare color
		String color;
		if (cardints[0] == 1 || cardints[0] == 2)
			color = "red";
		else
			color = "black";
		// set all buttons
		switch (i) {
		case 0:
			tgCard1.setText("<html><center><font color=\"" + color + "\">"
					+ values[cardints[1]] + "<br/>" + suits[cardints[0]]
					+ "</font></center></html>");
			break;
		case 1:
			tgCard2.setText("<html><center><font color=\"" + color + "\">"
					+ values[cardints[1]] + "<br/>" + suits[cardints[0]]
					+ "</font></center></html>");
			break;
		case 2:
			tgCard3.setText("<html><center><font color=\"" + color + "\">"
					+ values[cardints[1]] + "<br/>" + suits[cardints[0]]
					+ "</font></center></html>");
			break;
		case 3:
			tgCard4.setText("<html><center><font color=\"" + color + "\">"
					+ values[cardints[1]] + "<br/>" + suits[cardints[0]]
					+ "</font></center></html>");
			break;
		}

	}

	public void resetCards() {
		tgCard1.setText("");
		tgCard2.setText("");
		tgCard3.setText("");
		tgCard4.setText("");
	}

	public void setTfRaiseEnabled(boolean enabled) {
		tfRaise.setEnabled(enabled);
	}

	public void setButtonEnabled(String button, boolean enabled) {
		switch (button) {
		case "bet":
			btnBet.setEnabled(enabled);
			break;
		case "raise":
			btnRaise.setEnabled(enabled);
			break;
		case "check":
			btnCheck.setEnabled(enabled);
			break;
		case "call":
			btnCall.setEnabled(enabled);
			break;
		case "allin":
			btnAllin.setEnabled(enabled);
			break;
		case "fold":
			btnFold.setEnabled(enabled);
			break;
		case "exchange":
			btnExchange.setEnabled(enabled);
			break;
		}
	}

	public void enableStartButton(boolean enabled) {
		btnStart.setEnabled(enabled);
	}

	/**
	 * Set text to Status Bar
	 * 
	 * @param text
	 */
	public void setStBar(String text) {
		statusBar.setText(text);
	}

	public void setExchangedCards() {
		exchangedCards[0] = tgCard1.isSelected();
		exchangedCards[1] = tgCard2.isSelected();
		exchangedCards[2] = tgCard3.isSelected();
		exchangedCards[3] = tgCard4.isSelected();
	}

	public String exchangedCardsToString() {
		String s = "";
		for (int i = 0; i < exchangedCards.length; i++) {
			s += exchangedCards[i] ? "1" : "0";
			if (i < 3)
				s += " ";
		}
		return s;
	}

	/**
	 * Set text to label
	 * 
	 * @param type
	 * @param text
	 */
	public void setCashLbl(String type, int value) {
		switch (type) {
		case "balance":
			lblBalance.setText("" + value);
			break;
		case "bet":
			lblBet.setText("" + value);
			break;
		case "pot":
			lblPot.setText("" + value);
			break;
		case "maxbet":
			lblMaxBet.setText("" + value);
			break;
		}
	}

	/**
	 * Create the application.
	 */
	public ClientGUI() {
		initialize();
	}

	/**
	 * Toggle connection button and textfields
	 * 
	 * @param enable
	 */
	public void ToggleConnectDialog(boolean enabled) {
		tfPort.setEnabled(enabled);
		tfHost.setEnabled(enabled);
		tfNick.setEnabled(enabled);
		btnConnect.setEnabled(enabled);
		btnDisconnect.setEnabled(!enabled);
	}

	public void ToggleBetDialog(boolean enabled) {
		btnBet.setEnabled(enabled);
		btnRaise.setEnabled(enabled);
		btnCheck.setEnabled(enabled);
		btnCall.setEnabled(enabled);
		btnAllin.setEnabled(enabled);
		btnFold.setEnabled(enabled);
		tfRaise.setEnabled(enabled);
	}

	public void ToggleExchangeDialog(boolean enabled) {
		btnExchange.setEnabled(enabled);
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmBadugi = new JFrame();
		frmBadugi.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (c != null)
					c.send("disconnect " + c.nick);
			}
		});
		frmBadugi.setResizable(false);
		frmBadugi.setTitle("Badugi");
		frmBadugi.setBounds(100, 100, 800, 400);
		frmBadugi.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmBadugi.getContentPane().setLayout(new BorderLayout(4, 4));

		JPanel statusBarPanel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) statusBarPanel.getLayout();
		flowLayout.setVgap(3);
		flowLayout.setHgap(8);
		flowLayout.setAlignment(FlowLayout.LEFT);
		statusBarPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		frmBadugi.getContentPane().add(statusBarPanel, BorderLayout.SOUTH);

		statusBar = new JLabel("Not connected to server");
		statusBarPanel.add(statusBar);
		statusBar.setHorizontalAlignment(SwingConstants.LEFT);

		JPanel mainPanel = new JPanel();
		frmBadugi.getContentPane().add(mainPanel, BorderLayout.CENTER);
		mainPanel.setLayout(new GridLayout(0, 1, 0, 0));

		JPanel opponentsPanel = new JPanel();
		mainPanel.add(opponentsPanel);
		opponentsPanel
				.setLayout(new BoxLayout(opponentsPanel, BoxLayout.X_AXIS));

		op = new OpponentPanel[5];
		for (int i = 0; i < op.length; i++) {
			op[i] = new OpponentPanel();
			opponentsPanel.add(op[i]);
			if (i % 2 == 1)
				op[i].setBackground(new Color(220, 220, 220));
		}

		JPanel userPanel = new JPanel();
		userPanel.setBackground(UIManager.getColor("Viewport.background"));
		mainPanel.add(userPanel);
		userPanel.setLayout(null);

		tgCard1 = new JToggleButton("");
		tgCard1.setFont(new Font("Dialog", Font.BOLD, 32));
		tgCard1.setBounds(12, 50, 80, 108);
		userPanel.add(tgCard1);

		tgCard2 = new JToggleButton("");
		tgCard2.setFont(new Font("Dialog", Font.BOLD, 32));
		tgCard2.setBounds(104, 50, 80, 108);
		userPanel.add(tgCard2);

		tgCard3 = new JToggleButton("");
		tgCard3.setFont(new Font("Dialog", Font.BOLD, 32));
		tgCard3.setBounds(196, 50, 80, 108);
		userPanel.add(tgCard3);

		tgCard4 = new JToggleButton("");
		tgCard4.setFont(new Font("Dialog", Font.BOLD, 32));
		tgCard4.setBounds(288, 50, 80, 108);
		userPanel.add(tgCard4);

		btnExchange = new JButton("Exchange");
		btnExchange.setEnabled(false);
		btnExchange.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setExchangedCards();
				c.send("exchange " + exchangedCardsToString());
				setStBar("exchange " + exchangedCardsToString());
			}
		});
		btnExchange.setBounds(104, 12, 264, 26);
		userPanel.add(btnExchange);

		lblBalance = new JLabel("0");
		lblBalance.setHorizontalAlignment(SwingConstants.CENTER);
		lblBalance.setFont(new Font("Dialog", Font.BOLD, 28));
		lblBalance.setBounds(480, 115, 98, 43);
		userPanel.add(lblBalance);

		lblBet = new JLabel("0");
		lblBet.setHorizontalAlignment(SwingConstants.CENTER);
		lblBet.setFont(new Font("Dialog", Font.BOLD, 28));
		lblBet.setBounds(386, 115, 98, 43);
		userPanel.add(lblBet);

		JLabel lblBetInfo = new JLabel("your bet");
		lblBetInfo.setFont(new Font("Dialog", Font.PLAIN, 10));
		lblBetInfo.setHorizontalAlignment(SwingConstants.CENTER);
		lblBetInfo.setBounds(386, 100, 98, 16);
		userPanel.add(lblBetInfo);

		JLabel lblBalanceInfo = new JLabel("account balance");
		lblBalanceInfo.setHorizontalAlignment(SwingConstants.CENTER);
		lblBalanceInfo.setFont(new Font("Dialog", Font.PLAIN, 10));
		lblBalanceInfo.setBounds(480, 100, 98, 16);
		userPanel.add(lblBalanceInfo);

		btnStart = new JButton("Start");
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c.send("start");
			}
		});
		btnStart.setEnabled(false);
		btnStart.setBounds(12, 12, 80, 26);
		userPanel.add(btnStart);

		JLabel lblNewLabel = new JLabel("current pot");
		lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
		lblNewLabel.setFont(new Font("Dialog", Font.PLAIN, 10));
		lblNewLabel.setBounds(386, 32, 98, 16);
		userPanel.add(lblNewLabel);

		lblPot = new JLabel("0");
		lblPot.setFont(new Font("Dialog", Font.BOLD, 28));
		lblPot.setHorizontalAlignment(SwingConstants.CENTER);
		lblPot.setBounds(386, 50, 98, 43);
		userPanel.add(lblPot);

		lblMaxBet = new JLabel("0");
		lblMaxBet.setHorizontalAlignment(SwingConstants.CENTER);
		lblMaxBet.setFont(new Font("Dialog", Font.BOLD, 28));
		lblMaxBet.setBounds(480, 50, 98, 43);
		userPanel.add(lblMaxBet);

		lblNewLabel_1 = new JLabel("max bet");
		lblNewLabel_1.setHorizontalAlignment(SwingConstants.CENTER);
		lblNewLabel_1.setFont(new Font("Dialog", Font.PLAIN, 10));
		lblNewLabel_1.setBounds(480, 32, 98, 16);
		userPanel.add(lblNewLabel_1);

		JPanel rightPanel = new JPanel();
		frmBadugi.getContentPane().add(rightPanel, BorderLayout.EAST);

		JPanel loginPanel = new JPanel();

		tfHost = new JTextField();
		tfHost.setText("localhost");
		tfHost.setColumns(10);

		tfPort = new JTextField();
		tfPort.setText("9000");
		tfPort.setColumns(10);
		loginPanel.setLayout(new GridLayout(0, 1, 0, 0));

		JLabel lblHost = new JLabel("Host");
		lblHost.setHorizontalAlignment(SwingConstants.CENTER);
		loginPanel.add(lblHost);
		loginPanel.add(tfHost);

		JLabel lblPort = new JLabel("Port");
		lblPort.setHorizontalAlignment(SwingConstants.CENTER);
		loginPanel.add(lblPort);
		loginPanel.add(tfPort);

		JLabel lblNick = new JLabel("Nick");
		lblNick.setHorizontalAlignment(SwingConstants.CENTER);
		loginPanel.add(lblNick);

		tfNick = new JTextField();
		tfNick.setText("Player");
		loginPanel.add(tfNick);
		tfNick.setColumns(10);

		JPanel actionPanel = new JPanel();
		rightPanel.setLayout(new GridLayout(0, 1, 0, 0));
		rightPanel.add(loginPanel);

		btnConnect = new JButton("Connect");
		btnConnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int portn = 0;
				try {
					portn = Integer.parseInt(tfPort.getText());
					c = new Client(tfHost.getText(), portn, ClientGUI.this);
					c.connect();
					new Thread(c).start();
					ToggleConnectDialog(false);
					c.send("nick " + tfNick.getText());
					statusBar.setText("Connected with " + tfHost.getText()
							+ ":" + portn);
				} catch (NumberFormatException ex) {
					statusBar.setText("Invalid port");
				} catch (IOException io) {
					statusBar.setText(io.getMessage());
					c = null;
				} catch (Exception io) {
					statusBar.setText(io.getMessage());
					c = null;
				}
			}
		});
		loginPanel.add(btnConnect);

		btnDisconnect = new JButton("Disconnect");
		btnDisconnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c = null;
				statusBar.setText("Disconnected");
				ToggleConnectDialog(true);
				ToggleBetDialog(false);
			}
		});
		btnDisconnect.setEnabled(false);
		// loginPanel.add(btnDisconnect);
		rightPanel.add(actionPanel);
		actionPanel.setLayout(new GridLayout(0, 1, 0, 0));

		tfRaise = new JTextField();
		tfRaise.setToolTipText("Raise / bet value");
		tfRaise.setEnabled(false);
		tfRaise.setText("0");
		actionPanel.add(tfRaise);
		tfRaise.setColumns(10);

		btnBet = new JButton("Bet");
		btnBet.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					int value = Integer.parseInt(tfRaise.getText());
					c.send("bet " + value);
				} catch (NumberFormatException ex) {
					statusBar.setText("Invalid Bet value");
				}
			}
		});
		btnBet.setEnabled(false);
		actionPanel.add(btnBet);

		btnRaise = new JButton("Raise");
		btnRaise.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					int value = Integer.parseInt(tfRaise.getText());
					c.send("raise " + value);
				} catch (NumberFormatException ex) {
					statusBar.setText("Invalid Raise value");
				}

			}
		});
		btnRaise.setEnabled(false);
		actionPanel.add(btnRaise);

		btnCheck = new JButton("Check");
		btnCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c.send("check");
			}
		});
		btnCheck.setEnabled(false);
		btnCheck.setForeground(new Color(0, 128, 0));
		actionPanel.add(btnCheck);

		btnCall = new JButton("Call");
		btnCall.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c.send("call");
			}
		});
		btnCall.setEnabled(false);
		btnCall.setForeground(new Color(0, 128, 0));
		actionPanel.add(btnCall);

		btnAllin = new JButton("All-In");
		btnAllin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c.send("allin");
			}
		});
		btnAllin.setEnabled(false);
		actionPanel.add(btnAllin);

		btnFold = new JButton("Fold");
		btnFold.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				c.send("fold");
			}
		});
		btnFold.setEnabled(false);
		btnFold.setForeground(Color.RED);
		actionPanel.add(btnFold);
	}
}
